home *** CD-ROM | disk | FTP | other *** search
/ MacGames Sampler / PHT MacGames Bundle.iso / MacSource Folder / Samples from the CD / C and C++ / Gnuplot 3.5 for Macintosh / SOURCES 3.5 / parse.c < prev    next >
Text File  |  1993-11-12  |  12KB  |  634 lines

  1. #ifndef lint
  2. static char    *RCSid = "$Id: parse.c%v 3.50.1.8 1993/07/27 05:37:15 woo Exp $";
  3. #endif
  4.  
  5.  
  6. /* GNUPLOT - parse.c */
  7. /*
  8.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley 
  9.  *
  10.  * Permission to use, copy, and distribute this software and its documentation
  11.  * for any purpose with or without fee is hereby granted, provided that the
  12.  * above copyright notice appear in all copies and that both that copyright
  13.  * notice and this permission notice appear in supporting documentation. 
  14.  *
  15.  * Permission to modify the software is granted, but not the right to distribute
  16.  * the modified code.  Modifications are to be distributed as patches to
  17.  * released version. 
  18.  *
  19.  * This software is provided "as is" without express or implied warranty. 
  20.  *
  21.  *
  22.  * AUTHORS 
  23.  *
  24.  * Original Software: Thomas Williams,  Colin Kelley. 
  25.  *
  26.  * Gnuplot 2.0 additions: Russell Lang, Dave Kotz, John Campbell. 
  27.  *
  28.  * Gnuplot 3.0 additions: Gershon Elber and many others. 
  29.  *
  30.  */
  31.  
  32. #include <stdio.h>
  33. #include <setjmp.h>
  34. #include <signal.h>
  35. #include <errno.h>
  36. #include <math.h>
  37. #include "plot.h"
  38. #ifdef THINK_C
  39. #include "tout_protos.h"
  40. #endif
  41.  
  42. #ifndef vms
  43. #if !defined(__ZTC__) && !defined(__MSC__)
  44. extern int      errno;
  45. #endif
  46. #endif
  47.  
  48. extern int      num_tokens, c_token;
  49. extern struct lexical_unit token[];
  50. extern char     c_dummy_var[MAX_NUM_VAR][MAX_ID_LEN + 1];    /* name of current dummy
  51.                                  * vars */
  52. extern struct udft_entry *dummy_func;    /* pointer to dummy variable's func */
  53.  
  54. struct value   *
  55. pop(), *Ginteger(), *Gcomplex();
  56. struct at_type *
  57. temp_at(), *perm_at();
  58. struct udft_entry *add_udf();
  59. struct udvt_entry *add_udv();
  60. #ifdef THINK_C
  61. union argument *add_action(enum operators);
  62. #else
  63. union argument *add_action();
  64. #endif
  65.  
  66. struct at_type  at;
  67. #ifdef _Windows
  68. static jmp_buf far fpe_env;
  69. #else
  70. static jmp_buf  fpe_env;
  71. #endif
  72.  
  73. #define dummy (struct value *) 0
  74.  
  75. #if defined(__TURBOC__) || defined(DJGPP) || defined(SOLARIS)
  76. void
  77. fpe()
  78. #else
  79. #if defined( __ZTC__ ) || defined( _CRAY ) || defined( sgi )|| defined( OS2 ) || defined(__EMX__) || defined( __alpha)
  80. void
  81. fpe(an_int)
  82.     int             an_int;
  83. #else
  84. #if defined( NEXT ) || defined( VMS)
  85. void
  86. fpe(int an_int)
  87. #else
  88. #ifdef sgi
  89. void
  90. fpe(int sig, int code, struct sigcontext * sc)
  91. /*
  92.  * void fpe(an_int) int an_int; 
  93.  */
  94. #else
  95.  
  96. #ifdef THINK_C
  97. void fpe(void)
  98. #else
  99. fpe()
  100. #endif
  101.  
  102. #endif
  103. #endif
  104. #endif                /* __ZTC__ || _CRAY */
  105. #endif                /* __TURBOC__ */
  106. {
  107. #if defined(MSDOS) && !defined(__EMX__) && !defined(DJGPP) && !defined(_Windows) || defined(DOS386)
  108.     /* thanks to lotto@wjh12.UUCP for telling us about this  */
  109.     _fpreset();
  110. #endif
  111. #if defined(MSDOS) && defined(__EMX__)
  112.     (void)signal(SIGFPE, (void *)fpe);
  113. #else
  114. #ifdef DJGPP
  115.     (void)signal(SIGFPE, (SignalHandler)fpe);
  116. #else
  117. #ifdef OS2
  118.     (void) signal(an_int, SIG_ACK);
  119. #else
  120.     (void)signal(SIGFPE, 
  121.     #ifdef THINK_C 
  122.     (__sig_func)
  123.     #endif
  124.     fpe);
  125. #endif
  126. #endif
  127. #endif
  128. #ifdef ATARI
  129.     /* do we need this ? (AL) */
  130.     fprintf(stderr, "floating point exception!\n");
  131. #endif
  132.     undefined = TRUE;
  133.     longjmp(fpe_env, TRUE);
  134. }
  135.  
  136.  
  137. #ifdef apollo
  138. #include <apollo/base.h>
  139. #include <apollo/pfm.h>
  140. #include <apollo/fault.h>
  141.  
  142. /*
  143.  * On an Apollo, the OS can signal a couple errors that are not mapped into
  144.  * SIGFPE, namely signalling NaN and branch on an unordered comparison.  I
  145.  * suppose there are others, but none of these are documented, so I handle
  146.  * them as they arise. 
  147.  *
  148.  * Anyway, we need to catch these faults and signal SIGFPE. 
  149.  */
  150.  
  151. pfm_$fh_func_val_t apollo_sigfpe(pfm_$fault_rec_t & fault_rec)
  152. {
  153.     kill(getpid(), SIGFPE);
  154.     return pfm_$continue_fault_handling;
  155. }
  156.  
  157. apollo_pfm_catch()
  158. {
  159.     status_$t status;
  160.     pfm_$establish_fault_handler(fault_$fp_bsun, pfm_$fh_backstop,
  161.                        apollo_sigfpe, &status);
  162.     pfm_$establish_fault_handler(fault_$fp_sig_nan, pfm_$fh_backstop,
  163.                        apollo_sigfpe, &status);
  164. }
  165. #endif
  166.  
  167.  
  168. evaluate_at(at_ptr, val_ptr)
  169.     struct at_type *at_ptr;
  170.     struct value   *val_ptr;
  171. {
  172.     double          temp, real();
  173.  
  174.     undefined = FALSE;
  175.     errno = 0;
  176.     reset_stack();
  177.  
  178. #ifndef DOSX286
  179.     if (setjmp(fpe_env))
  180.         return(0);        /* just bail out */
  181. #if defined(MSDOS) && defined(__EMX__)
  182.     (void)signal(SIGFPE, (void *)fpe);
  183. #else
  184. #if DJGPP
  185.     (void)signal(SIGFPE, (SignalHandler)fpe);
  186. #else
  187.     (void)signal(SIGFPE,
  188.     #ifdef THINK_C
  189.     (__sig_func)
  190.     #endif
  191.      fpe);    /* catch core dumps on FPEs */
  192. #endif
  193. #endif
  194. #endif
  195.  
  196.     execute_at(at_ptr);
  197.  
  198. #ifndef DOSX286
  199.     (void)signal(SIGFPE, SIG_DFL);
  200. #endif
  201.  
  202.     if (errno == EDOM || errno == ERANGE) {
  203.         undefined = TRUE;
  204.     } else {
  205.         (void)pop(val_ptr);
  206.         check_stack();
  207.     }
  208.     /* At least one machine (ATT 3b1) computes Inf without a SIGFPE */
  209.     temp = real(val_ptr);
  210.     if (temp > VERYLARGE || temp < -VERYLARGE) {
  211.         undefined = TRUE;
  212.     }
  213. }
  214.  
  215.  
  216. struct value   *
  217. const_express(valptr)
  218.     struct value   *valptr;
  219. {
  220.     register int    tkn = c_token;
  221.     if (END_OF_COMMAND)
  222.         int_error("constant expression required", c_token);
  223.     evaluate_at(temp_at(), valptr);    /* run it and send answer back */
  224.     if (undefined) {
  225.         int_error("undefined value", tkn);
  226.     }
  227.     return (valptr);
  228. }
  229.  
  230.  
  231. struct at_type *
  232. temp_at()
  233. {                /* build a static action table and return its
  234.                  * pointer */
  235.     at.a_count = 0;        /* reset action table !!! */
  236.     express();
  237.     return (&at);
  238. }
  239.  
  240.  
  241. /* build an action table, put it in dynamic memory, and return its pointer */
  242.  
  243. struct at_type *
  244. perm_at()
  245. {
  246.     register struct at_type *at_ptr;
  247.     unsigned int len;
  248.  
  249.     (void)temp_at();
  250.     len = sizeof(struct at_type) -
  251.         (MAX_AT_LEN - at.a_count) * sizeof(struct at_entry);
  252.     at_ptr = (struct at_type *) alloc((unsigned long)len, "action table");
  253.     (void)memcpy(at_ptr, &at, len);
  254.     return (at_ptr);
  255. }
  256.  
  257.  
  258. #ifdef NOCOPY
  259. /*
  260.  * cheap and slow version of memcpy() in case you don't have one 
  261.  */
  262. memcpy(dest, src, len)
  263.     char           *dest, *src;
  264.     unsigned int    len;
  265. {
  266.     while (len--)
  267.         *dest++ = *src++;
  268. }
  269. #endif                /* NOCOPY */
  270.  
  271.  
  272. express()
  273. {                /* full expressions */
  274.     xterm();
  275.     xterms();
  276. }
  277.  
  278. xterm()
  279. {                /* ? : expressions */
  280.     aterm();
  281.     aterms();
  282. }
  283.  
  284.  
  285. aterm()
  286. {
  287.     bterm();
  288.     bterms();
  289. }
  290.  
  291.  
  292. bterm()
  293. {
  294.     cterm();
  295.     cterms();
  296. }
  297.  
  298.  
  299. cterm()
  300. {
  301.     dterm();
  302.     dterms();
  303. }
  304.  
  305.  
  306. dterm()
  307. {
  308.     eterm();
  309.     eterms();
  310. }
  311.  
  312.  
  313. eterm()
  314. {
  315.     fterm();
  316.     fterms();
  317. }
  318.  
  319.  
  320. fterm()
  321. {
  322.     gterm();
  323.     gterms();
  324. }
  325.  
  326.  
  327. gterm()
  328. {
  329.     hterm();
  330.     hterms();
  331. }
  332.  
  333.  
  334. hterm()
  335. {
  336.     unary();        /* - things */
  337.     iterms();        /* * / % */
  338. }
  339.  
  340.  
  341. factor()
  342. {
  343.     register int    value;
  344.  
  345.     if (equals(c_token, "(")) {
  346.         c_token++;
  347.         express();
  348.         if (!equals(c_token, ")"))
  349.             int_error("')' expected", c_token);
  350.         c_token++;
  351.     } else if (isnumber(c_token)) {
  352.         convert(&(add_action(PUSHC)->v_arg), c_token);
  353.         c_token++;
  354.     } else if (isletter(c_token)) {
  355.         if ((c_token + 1 < num_tokens) && equals(c_token + 1, "(")) {
  356.             value = standard(c_token);
  357.             if (value) {    /* it's a standard function */
  358.                 c_token += 2;
  359.                 express();
  360.                 if (equals(c_token, ",")) {
  361.                     while (equals(c_token, ",")) {
  362.                         c_token += 1;
  363.                         express();
  364.                     }
  365.                 }
  366.                 if (!equals(c_token, ")"))
  367.                     int_error("')' expected", c_token);
  368.                 c_token++;
  369.                 (void)add_action(value);
  370.             } else {
  371.                 int             call_type = (int)CALL;
  372.                 value = c_token;
  373.                 c_token += 2;
  374.                 express();
  375.                 if (equals(c_token, ",")) {
  376.                     struct value    num_params;
  377.                     num_params.type = INTGR;
  378.                     num_params.v.int_val = 1;
  379.                     while (equals(c_token, ",")) {
  380.                         num_params.v.int_val += 1;
  381.                         c_token += 1;
  382.                         express();
  383.                     }
  384.                     add_action(PUSHC)->v_arg = num_params;
  385.                     call_type = (int)CALLN;
  386.                 }
  387.                 if (!equals(c_token, ")"))
  388.                     int_error("')' expected", c_token);
  389.                 c_token++;
  390.                 add_action(call_type)->udf_arg = add_udf(value);
  391.             }
  392.         } else {
  393.             if (equals(c_token, c_dummy_var[0])) {
  394.                 c_token++;
  395.                 add_action(PUSHD1)->udf_arg = dummy_func;
  396.             } else if (equals(c_token, c_dummy_var[1])) {
  397.                 c_token++;
  398.                 add_action(PUSHD2)->udf_arg = dummy_func;
  399.             } else {
  400.                 int             i, param = 0;
  401.                 for (i = 2; i < MAX_NUM_VAR; i++) {
  402.                     if (equals(c_token, c_dummy_var[i])) {
  403.                         struct value    num_params;
  404.                         num_params.type = INTGR;
  405.                         num_params.v.int_val = i;
  406.                         param = 1;
  407.                         c_token++;
  408.                         add_action(PUSHC)->v_arg = num_params;
  409.                         add_action(PUSHD)->udf_arg = dummy_func;
  410.                         break;
  411.                     }
  412.                 }
  413.                 if (!param) {    /* defined variable */
  414.                     add_action(PUSH)->udv_arg = add_udv(c_token);
  415.                     c_token++;
  416.                 }
  417.             }
  418.         }
  419.     }
  420.     /* end if letter */
  421.     else
  422.         int_error("invalid expression ", c_token);
  423.  
  424.     /* add action code for ! (factorial) operator */
  425.     while (equals(c_token, "!")) {
  426.         c_token++;
  427.         (void)add_action(FACTORIAL);
  428.     }
  429.     /* add action code for ** operator */
  430.     if (equals(c_token, "**")) {
  431.         c_token++;
  432.         unary();
  433.         (void)add_action(POWER);
  434.     }
  435. }
  436.  
  437.  
  438.  
  439. xterms()
  440. {                /* create action code for ? : expressions */
  441.  
  442.     if (equals(c_token, "?")) {
  443.         register int    savepc1, savepc2;
  444.         register union argument *argptr1, *argptr2;
  445.         c_token++;
  446.         savepc1 = at.a_count;
  447.         argptr1 = add_action(JTERN);
  448.         express();
  449.         if (!equals(c_token, ":"))
  450.             int_error("expecting ':'", c_token);
  451.         c_token++;
  452.         savepc2 = at.a_count;
  453.         argptr2 = add_action(JUMP);
  454.         argptr1->j_arg = at.a_count - savepc1;
  455.         express();
  456.         argptr2->j_arg = at.a_count - savepc2;
  457.     }
  458. }
  459.  
  460.  
  461. aterms()
  462. {                /* create action codes for || operator */
  463.  
  464.     while (equals(c_token, "||")) {
  465.         register int    savepc;
  466.         register union argument *argptr;
  467.         c_token++;
  468.         savepc = at.a_count;
  469.         argptr = add_action(JUMPNZ);    /* short-circuit if already
  470.                          * TRUE */
  471.         aterm();
  472.         argptr->j_arg = at.a_count - savepc;    /* offset for jump */
  473.         (void)add_action(BOOLE);
  474.     }
  475. }
  476.  
  477.  
  478. bterms()
  479. {                /* create action code for && operator */
  480.  
  481.     while (equals(c_token, "&&")) {
  482.         register int    savepc;
  483.         register union argument *argptr;
  484.         c_token++;
  485.         savepc = at.a_count;
  486.         argptr = add_action(JUMPZ);    /* short-circuit if already
  487.                          * FALSE */
  488.         bterm();
  489.         argptr->j_arg = at.a_count - savepc;    /* offset for jump */
  490.         (void)add_action(BOOLE);
  491.     }
  492. }
  493.  
  494.  
  495. cterms()
  496. {                /* create action code for | operator */
  497.  
  498.     while (equals(c_token, "|")) {
  499.         c_token++;
  500.         cterm();
  501.         (void)add_action(BOR);
  502.     }
  503. }
  504.  
  505.  
  506. dterms()
  507. {                /* create action code for ^ operator */
  508.  
  509.     while (equals(c_token, "^")) {
  510.         c_token++;
  511.         dterm();
  512.         (void)add_action(XOR);
  513.     }
  514. }
  515.  
  516.  
  517. eterms()
  518. {                /* create action code for & operator */
  519.  
  520.     while (equals(c_token, "&")) {
  521.         c_token++;
  522.         eterm();
  523.         (void)add_action(BAND);
  524.     }
  525. }
  526.  
  527.  
  528. fterms()
  529. {                /* create action codes for == and !=
  530.                  * operators */
  531.  
  532.     while (TRUE) {
  533.         if (equals(c_token, "==")) {
  534.             c_token++;
  535.             fterm();
  536.             (void)add_action(EQ);
  537.         } else if (equals(c_token, "!=")) {
  538.             c_token++;
  539.             fterm();
  540.             (void)add_action(NE);
  541.         } else
  542.             break;
  543.     }
  544. }
  545.  
  546.  
  547. gterms()
  548. {                /* create action code for < > >= or <=
  549.                  * operators */
  550.  
  551.     while (TRUE) {
  552.         /* I hate "else if" statements */
  553.         if (equals(c_token, ">")) {
  554.             c_token++;
  555.             gterm();
  556.             (void)add_action(GT);
  557.         } else if (equals(c_token, "<")) {
  558.             c_token++;
  559.             gterm();
  560.             (void)add_action(LT);
  561.         } else if (equals(c_token, ">=")) {
  562.             c_token++;
  563.             gterm();
  564.             (void)add_action(GE);
  565.         } else if (equals(c_token, "<=")) {
  566.             c_token++;
  567.             gterm();
  568.             (void)add_action(LE);
  569.         } else
  570.             break;
  571.     }
  572.  
  573. }
  574.  
  575.  
  576.  
  577. hterms()
  578. {                /* create action codes for + and - operators */
  579.  
  580.     while (TRUE) {
  581.         if (equals(c_token, "+")) {
  582.             c_token++;
  583.             hterm();
  584.             (void)add_action(PLUS);
  585.         } else if (equals(c_token, "-")) {
  586.             c_token++;
  587.             hterm();
  588.             (void)add_action(MINUS);
  589.         } else
  590.             break;
  591.     }
  592. }
  593.  
  594.  
  595. iterms()
  596. {                /* add action code for * / and % operators */
  597.  
  598.     while (TRUE) {
  599.         if (equals(c_token, "*")) {
  600.             c_token++;
  601.             unary();
  602.             (void)add_action(MULT);
  603.         } else if (equals(c_token, "/")) {
  604.             c_token++;
  605.             unary();
  606.             (void)add_action(DIV);
  607.         } else if (equals(c_token, "%")) {
  608.             c_token++;
  609.             unary();
  610.             (void)add_action(MOD);
  611.         } else
  612.             break;
  613.     }
  614. }
  615.  
  616.  
  617. unary()
  618. {                /* add code for unary operators */
  619.     if (equals(c_token, "!")) {
  620.         c_token++;
  621.         unary();
  622.         (void)add_action(LNOT);
  623.     } else if (equals(c_token, "~")) {
  624.         c_token++;
  625.         unary();
  626.         (void)add_action(BNOT);
  627.     } else if (equals(c_token, "-")) {
  628.         c_token++;
  629.         unary();
  630.         (void)add_action(UMINUS);
  631.     } else
  632.         factor();
  633. }
  634.